package com.codebo.yunpicturebackend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codebo.yunpicturebackend.common.ErrorCode;
import com.codebo.yunpicturebackend.constant.CommonConstant;
import com.codebo.yunpicturebackend.constant.UserConstant;
import com.codebo.yunpicturebackend.exception.ThrowUtils;
import com.codebo.yunpicturebackend.mapper.UserMapper;
import com.codebo.yunpicturebackend.model.dto.user.*;
import com.codebo.yunpicturebackend.model.entity.User;
import com.codebo.yunpicturebackend.model.enums.UserRoleEnum;
import com.codebo.yunpicturebackend.model.vo.LoginUserVO;
import com.codebo.yunpicturebackend.model.vo.UserVO;
import com.codebo.yunpicturebackend.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.codebo.yunpicturebackend.constant.UserConstant.USER_LOGIN_STATE;

/**
 * @author 25912
 * @description 针对表【user(用户)】的数据库操作Service实现
 * @createDate 2025-08-11 17:51:42
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService
{

    @Override
    public long userRegister(UserRegisterDTO userRegisterDTO)
    {
        //1.参数校验
        String userAccount = userRegisterDTO.getUserAccount();
        String userPassword = userRegisterDTO.getUserPassword();
        String checkPassword = userRegisterDTO.getCheckPassword();
        ThrowUtils.throwIf(userAccount == null || userPassword == null || checkPassword == null, ErrorCode.PARAMS_ERROR, "注册参数存在空值");
        ThrowUtils.throwIf(userAccount.length() < 3, ErrorCode.PARAMS_ERROR, "用户账号过短");
        ThrowUtils.throwIf(userPassword.length() < 3 || checkPassword.length() < 3, ErrorCode.PARAMS_ERROR, "用户密码过短");
        ThrowUtils.throwIf(userAccount.length() > 15, ErrorCode.PARAMS_ERROR, "用户账号过长");
        ThrowUtils.throwIf(userPassword.length() > 15, ErrorCode.PARAMS_ERROR, "用户密码过长");
        ThrowUtils.throwIf(!userPassword.equals(checkPassword), ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
        //2.用户名是否重复
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);
        ThrowUtils.throwIf(this.count(queryWrapper) > 0, ErrorCode.PARAMS_ERROR, "用户名已存在");
        //3.密码加盐加密
        String encryptedPassword = getEncryptPassword(userPassword);
        //4.插入数据
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(encryptedPassword);
        user.setUserName("用户" + userAccount);
        user.setUserRole(UserConstant.DEFAULT_ROLE);
        boolean save = this.save(user);
        ThrowUtils.throwIf(!save, ErrorCode.SYSTEM_ERROR, "用户注册失败，保存数据出现错误");
        return user.getId();


    }

    @Override
    public LoginUserVO userLogin(UserLoginDTO userLoginDTO, HttpServletRequest httpServletRequest)
    {
        String userAccount = userLoginDTO.getUserAccount();
        String userPassword = userLoginDTO.getUserPassword();
        //1.参数校验
        ThrowUtils.throwIf(userAccount == null || userPassword == null, ErrorCode.PARAMS_ERROR, "登录参数存在空值");
        ThrowUtils.throwIf(userAccount.length() < 3, ErrorCode.PARAMS_ERROR, "用户账号过短");
        ThrowUtils.throwIf(userPassword.length() < 3, ErrorCode.PARAMS_ERROR, "用户密码过短");
        ThrowUtils.throwIf(userAccount.length() > 15, ErrorCode.PARAMS_ERROR, "用户账号过长");
        ThrowUtils.throwIf(userPassword.length() > 15, ErrorCode.PARAMS_ERROR, "用户密码过长");
        //2.密码加盐加密
        String encryptPassword = getEncryptPassword(userPassword);
        //3.用户名是否存在
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);
        queryWrapper.eq("userPassword", encryptPassword);
        User user = this.baseMapper.selectOne(queryWrapper);
        ThrowUtils.throwIf(user == null, ErrorCode.PARAMS_ERROR, "用户不存在");
        //4.保存登录态
        httpServletRequest.getSession().setAttribute(USER_LOGIN_STATE, user);
        return getLoginUserVO(user);
    }

    @Override
    public boolean userLogout(HttpServletRequest httpServletRequest)
    {
        Object userObj = httpServletRequest.getSession().getAttribute(USER_LOGIN_STATE);
        User currentUser = (User) userObj;
        ThrowUtils.throwIf(currentUser == null || currentUser.getId() == null, ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
        httpServletRequest.getSession().removeAttribute(USER_LOGIN_STATE);
        return true;
    }

    @Override
    public long addUser(UserAddDTO userAddDTO)
    {
        String userName = userAddDTO.getUserName();
        String userAccount = userAddDTO.getUserAccount();
        String userAvatar = userAddDTO.getUserAvatar();
        String userProfile = userAddDTO.getUserProfile();
        String userRole = userAddDTO.getUserRole();
        //1.参数校验
        ThrowUtils.throwIf(userAccount == null, ErrorCode.PARAMS_ERROR, "添加用户参数存在空值");
        ThrowUtils.throwIf(userName.length() > 15, ErrorCode.PARAMS_ERROR, "用户名过长");
        ThrowUtils.throwIf(userAccount.length() < 3, ErrorCode.PARAMS_ERROR, "用户账号过短");
        ThrowUtils.throwIf(userAccount.length() > 15, ErrorCode.PARAMS_ERROR, "用户账号过长");
        ThrowUtils.throwIf(userProfile.length() > 100, ErrorCode.PARAMS_ERROR, "用户简介过长");
        if (StrUtil.isEmpty(userName))
        {
            userAddDTO.setUserName("用户" + userAccount);
        }
        if (!ObjUtil.isNotNull(UserRoleEnum.getEnumByValue(userRole)))
        {
            userAddDTO.setUserRole(UserConstant.DEFAULT_ROLE);
        }
        //2.用户名是否重复
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);
        ThrowUtils.throwIf(this.count(queryWrapper) > 0, ErrorCode.PARAMS_ERROR, "用户已存在");
        //3.密码加盐加密
        String encryptedPassword = getEncryptPassword(UserConstant.DEFAULT_PASSWORD);
        //4.保存数据
        User user = new User();
        BeanUtil.copyProperties(userAddDTO, user);
        user.setUserPassword(encryptedPassword);
        boolean save = this.save(user);

        return user.getId();
    }

    @Override
    public User getUserById(Long id)
    {
        User user = this.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
        return user;
    }

    @Override
    public boolean updateUser(UserUpdateDTO userUpdateDTO)
    {
        long id = userUpdateDTO.getId();
        String userName = userUpdateDTO.getUserName();
        String userAvatar = userUpdateDTO.getUserAvatar();
        String userProfile = userUpdateDTO.getUserProfile();
        String userRole = userUpdateDTO.getUserRole();
        //1.参数校验
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR, "用户id小于等于0");
        ThrowUtils.throwIf(userName.length() < 3 , ErrorCode.PARAMS_ERROR, "用户名过短");
        ThrowUtils.throwIf(userName.length() > 15, ErrorCode.PARAMS_ERROR, "用户名过长");
        ThrowUtils.throwIf(userProfile.length() > 100, ErrorCode.PARAMS_ERROR, "用户简介过长");
        ThrowUtils.throwIf(!ObjUtil.isNotNull(UserRoleEnum.getEnumByValue(userRole)), ErrorCode.PARAMS_ERROR, "用户角色不存在");
        //2.用户是否存在
        User user = this.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
        BeanUtil.copyProperties(userUpdateDTO, user);
        return this.updateById(user);
    }

    @Override
    public LoginUserVO getLoginUserVO(User user)
    {
        if (user == null)
        {
            return null;
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(user, loginUserVO);
        return loginUserVO;
    }

    @Override
    public UserVO getUserVO(User user)
    {
        if (user == null)
        {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public List<UserVO> getUserVOList(List<User> user)
    {
        if (CollectionUtils.isEmpty(user))
        {
            return new ArrayList<>();
        }
        return user.stream().map(this::getUserVO).collect(Collectors.toList());
    }

    @Override
    public QueryWrapper<User> getQueryWrapper(UserQueryDTO userQueryDTO)
    {
        ThrowUtils.throwIf(userQueryDTO == null, ErrorCode.PARAMS_ERROR, "请求为空");
        Long id = userQueryDTO.getId();
        String userName = userQueryDTO.getUserName();
        String userAccount = userQueryDTO.getUserAccount();
        String userProfile = userQueryDTO.getUserProfile();
        String userRole = userQueryDTO.getUserRole();
        String sortField = userQueryDTO.getSortField();
        String sortOrder = userQueryDTO.getSortOrder();

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjUtil.isNotNull(id), "id", id);
        queryWrapper.eq(StringUtils.isNotBlank(userRole), "userRole", userRole);
        queryWrapper.like(StringUtils.isNotBlank(userName), "userName", userName);
        queryWrapper.like(StringUtils.isNotBlank(userAccount), "userAccount", userAccount);
        queryWrapper.like(StringUtils.isNotBlank(userProfile), "userProfile", userProfile);
        queryWrapper.orderBy(StringUtils.isNotBlank(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
        return queryWrapper;
    }

    @Override
    public boolean isAdmin(User user)
    {
        return user != null && UserRoleEnum.ADMIN.getValue().equals(user.getUserRole());

    }


    @Override
    public User getcurrentUser(HttpServletRequest httpServletRequest)
    {
        Object userObj = httpServletRequest.getSession().getAttribute(USER_LOGIN_STATE);
        User currentUser = (User) userObj;
        ThrowUtils.throwIf(currentUser == null || currentUser.getId() == null, ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
        return currentUser;
    }

//----工具方法-------------------------------------------------------------------------

    public String getEncryptPassword(String userPassword)
    {
        String saltPassword = userPassword + UserConstant.PASSWORD_SALT;
        return SecureUtil.sha256(saltPassword);
    }
}




